/**************************************************************************************************
**                                                                                               **
**  文件名称:  nft_list.c                                                                        **
**  版权所有:  CopyRight @ Xiamen Yaxon NetWork CO.LTD. 2017                                     **
**  文件描述:  链表管理功能抽象化                                                                **
**  ===========================================================================================  **
**  创建信息:  | 2017-3-20 | LEON | 创建本模块                                                   **
**  ===========================================================================================  **
**  修改信息:  单击此处添加....                                                                  **
**************************************************************************************************/
#include "nft_include.h"
#include "nft_list.h"

/**************************************************************************************************
**  函数名称:  LIST_GetNodeNum
**  功能描述:  获取链表节点个数
**  输入参数:  plist: 链表指针
**  输出参数:  无
**  返回参数:  返回链表结点个数
**************************************************************************************************/
INT32U LIST_GetNodeNum(LIST_T *plist)
{
    if (plist == 0) {
        return 0;
    } else {
        return (plist->inum);
    }
}

/**************************************************************************************************
**  函数名称:  LIST_GetListHead
**  功能描述:  获取链表头节点
**  输入参数:  plist: 链表指针
**  输出参数:  无
**  返回参数:  链表头节点; 如链表无节点, 则返回0
**************************************************************************************************/
INT8U *LIST_GetListHead(LIST_T *plist)
{
    if (plist == 0 || plist->inum == 0) {
        return 0;
    } else {
        return (((INT8U *)plist->head) + sizeof(NODE_T));
    }
}

/**************************************************************************************************
**  函数名称:  LIST_GetListTail
**  功能描述:  获取链表尾节点
**  输入参数:  plist: 链表指针
**  输出参数:  无
**  返回参数:  链表尾节点; 如链表无节点, 则返回0
**************************************************************************************************/
INT8U *LIST_GetListTail(LIST_T *plist)
{
    if (plist == 0 || plist->inum == 0) {
        return 0;
    } else {
        return (((INT8U *)plist->tail) + sizeof(NODE_T));
    }
}

/**************************************************************************************************
**  函数名称:  LIST_GetNextEle
**  功能描述:  获取指定节点的下一个节点
**  输入参数:  plist: 链表指针
**  输出参数:  无
**  返回参数:  返回下一个节点指针; 无结点返回0
**************************************************************************************************/
INT8U *LIST_GetNextEle(INT8U *pnode)
{
    NODE_T *curnode;
	
    if (pnode == 0) {
        return 0;
    }
    
    curnode = (NODE_T *)(((INT8U *)pnode) - sizeof(NODE_T));
    if ((curnode = curnode->next) == 0) {
        return 0;
    } else {
        return (((INT8U *)curnode) + sizeof(NODE_T));
    }
}

/**************************************************************************************************
**  函数名称:  LIST_GetPrivEle
**  功能描述:  获取指定节点的前一个节点
**  输入参数:  plist: 链表指针
**  输出参数:  无
**  返回参数:  返回前一节点指针; 无结点返回0
**************************************************************************************************/
INT8U *LIST_GetPrivEle(INT8U *pnode)
{
    NODE_T *curnode;

    if (pnode == 0) {
        return 0;
    }
    
    curnode = (NODE_T *)(((INT8U *)pnode) - sizeof(NODE_T));
    if ((curnode = curnode->priv) == 0) {
        return 0;
    } else {
        return (((INT8U *)curnode) + sizeof(NODE_T));
    }
}

/**************************************************************************************************
**  函数名称:  LIST_DeleListEle
**  功能描述:  删除指定节点，并返回下一个结点指针
**  输入参数:  plist: 链表指针; pnode: 链表当前节点
**  输出参数:  无
**  返回参数:  返回下一个节点指针; 无结点返回0
**************************************************************************************************/
INT8U *LIST_DeleListEle(LIST_T *plist, INT8U *pnode)
{
    NODE_T *curnode, *privnode, *nextnode;

    if (plist == 0 || pnode == 0) {
        return 0;
    }
    
    if (plist->inum == 0) {
        return 0;
    }

    plist->inum--;
    curnode  = (NODE_T *)(((INT8U *)pnode) - sizeof(NODE_T));
    privnode = curnode->priv;
    nextnode = curnode->next;
    if (privnode == 0) {
        plist->head = nextnode;
    } else {
        privnode->next = nextnode;
    }
    
    if (nextnode == 0) {
        plist->tail = privnode;
        return 0;
    } else {
        nextnode->priv = privnode;
        return (((INT8U *)nextnode) + sizeof(NODE_T));
    }
}

/**************************************************************************************************
**  函数名称:  LIST_DeleListHead
**  功能描述:  删除链表头节点,返回头结点指针
**  输入参数:  plist: 链表指针
**  输出参数:  无
**  返回参数:  返回链表头节点指针; 无结点返回0
**************************************************************************************************/
INT8U *LIST_DeleListHead(LIST_T *plist)
{
    INT8U *pnode;

    if (plist == 0 || plist->inum == 0) {
        return 0;
    }

    pnode = ((INT8U *)plist->head) + sizeof(NODE_T);
    LIST_DeleListEle(plist, pnode);
    return pnode;
}

/**************************************************************************************************
**  函数名称:  LIST_DeleListTail
**  功能描述:  删除链表尾节点,返回链表尾结点指针
**  输入参数:  plist: 链表指针
**  输出参数:  无
**  返回参数:  返回链表尾节点指针; 无结点返回0
**************************************************************************************************/
INT8U *LIST_DeleListTail(LIST_T *plist)
{
    INT8U *pnode;

    if (plist == 0 || plist->inum == 0) {
        return 0;
    }

    pnode = (INT8U *)plist->tail + sizeof(NODE_T);
    LIST_DeleListEle(plist, pnode);
    return pnode;
}

/**************************************************************************************************
**  函数名称:  LIST_AppendListEle
**  功能描述:  将新增节点插在链表尾
**  输入参数:  plist: 链表指针; pnode: 待挂接节点
**  输出参数:  无
**  返回参数:  成功返回true,失败返回false
**************************************************************************************************/
BOOLEAN LIST_AppendListEle(LIST_T *plist, INT8U *pnode)
{
    NODE_T *curnode;

    if (plist == 0 || pnode == 0) {
        return FALSE;
    }

    curnode = (NODE_T *)(((INT8U *)pnode) - sizeof(NODE_T));
    curnode->priv = plist->tail;
    if (plist->inum == 0) {
        plist->head = curnode;
    } else {
        plist->tail->next = curnode;
    }
    curnode->next = 0;
    plist->tail = curnode;
    plist->inum++;
    return TRUE;
}

/**************************************************************************************************
**  函数名称:  LIST_InsertListHead
**  功能描述:  将新增结点插在链表头
**  输入参数:  plist: 链表指针; pnode: 新增节点
**  输出参数:  无
**  返回参数:  成功返回true,失败返回false
**************************************************************************************************/
BOOLEAN LIST_InsertListHead(LIST_T *plist, INT8U *pnode)
{
    NODE_T *curnode;

    if (plist == 0 || pnode == 0) {
        return FALSE;
    }

    curnode = (NODE_T *)(((INT8U *)pnode) - sizeof(NODE_T));
    curnode->next = plist->head;
    if (plist->inum == 0) {
        plist->tail = curnode;
    } else {
        plist->head->priv = curnode;
    }
    curnode->priv = 0;
    plist->head = curnode;
    plist->inum++;
    return TRUE;
}

/**************************************************************************************************
**  函数名称:  LIST_InsertNodeBefore
**  功能描述:  在指定节点前插入一个新节点
**  输入参数:  plist: 链表指针; cnode: 指定节点; dnode: 新增节点
**  输出参数:  无
**  返回参数:  成功返回true,失败返回false
**************************************************************************************************/
BOOLEAN LIST_InsertNodeBefore(LIST_T *plist, INT8U *cnode, INT8U *dnode)
{
    NODE_T *curnode, *insnode;
	
    if (plist == 0 || cnode == 0 || dnode == 0) {
        return FALSE;
    }
    
    if (plist->inum == 0) {
        return FALSE;
    }

    curnode  = (NODE_T *)(((INT8U *)cnode) - sizeof(NODE_T));
    insnode  = (NODE_T *)(((INT8U *)dnode) - sizeof(NODE_T));

    insnode->next = curnode;
    insnode->priv = curnode->priv;
    if (curnode->priv == 0){
        plist->head = insnode;
    } else {
        curnode->priv->next = insnode;
    }
    curnode->priv = insnode;
    plist->inum++;
    return TRUE;
}

/**************************************************************************************************
**  函数名称:  LIST_InsertNodeAfter
**  功能描述:  在指定节点后插入一个新节点
**  输入参数:  plist: 链表指针; cnode: 指定节点; dnode: 新增节点
**  输出参数:  无
**  返回参数:  成功返回true,失败返回false
**************************************************************************************************/
BOOLEAN LIST_InsertNodeAfter(LIST_T *plist, INT8U *cnode, INT8U *dnode)
{
    NODE_T *curnode, *insnode;

    if (plist == 0 || cnode == 0 || dnode == 0) {
        return FALSE;
    }
    
    if (plist->inum == 0) {
        return FALSE;
    }
    
    curnode = (NODE_T *)(((INT8U *)cnode) - sizeof(NODE_T));
    insnode = (NODE_T *)(((INT8U *)dnode) - sizeof(NODE_T));
    
    insnode->next = curnode->next;
    insnode->priv = curnode;
    if(curnode->next == 0) {
        plist->tail = insnode;
    } else {
        curnode->next->priv = insnode;
    }
    curnode->next = insnode;
    plist->inum++;
    return TRUE;
}

/**************************************************************************************************
**  函数名称:  LIST_Init
**  功能描述:  初始化链表
**  输入参数:  plist: 链表指针
**  输出参数:  无
**  返回参数:  成功返回true,失败返回false
**************************************************************************************************/
BOOLEAN LIST_Init(LIST_T *plist)
{
    if (plist == 0) {
        return FALSE;
    }
	
    plist->head = 0;
    plist->tail = 0;
    plist->inum = 0;
    return TRUE;
}

/**************************************************************************************************
**  函数名称:  LIST_CreateList
**  功能描述:  创建一个列表
**  输入参数:  plist: 链表指针; nodeptr: 节点首地址; nodenum: 节点个数; nodesize: 节点大小
**  输出参数:  无
**  返回参数:  成功返回true,失败返回false
**************************************************************************************************/
BOOLEAN LIST_CreateList(LIST_T *plist, INT8U *nodeptr, INT32U nodenum, INT32U nodesize)
{
    if (!LIST_Init(plist)) {
        return FALSE;
    }

    nodeptr += sizeof(NODE_T);
    for(; nodenum > 0; nodenum--){
        if (!LIST_AppendListEle(plist, nodeptr)) {
            return FALSE;
        }
        nodeptr += nodesize;
    }
    return TRUE;
}

/**************************************************************************************************
**  函数名称:  LIST_CheckError
**  功能描述:  检测链表的有效性
**  输入参数:  plist: 链表指针; bptr:  最小地址; eptr:  最大地址
**  输出参数:  无
**  返回参数:  有效返回true,无效返回false
**************************************************************************************************/
BOOLEAN LIST_CheckError(LIST_T *plist, void *bptr, void *eptr)
{
    INT32U    count;
    NODE_T *curnode;
	
    if (plist == 0) {
        return FALSE;
    }
    
    count = 0;
    curnode = plist->head;
    while (curnode != 0) {
        if (((void *)curnode < bptr) || ((void *)curnode > eptr)) {
            return FALSE;
        }
        
        if (++count > plist->inum) {
            return FALSE;
        }
        curnode = curnode->next;
    }
    
    if (count != plist->inum) {
        return FALSE;
    }
	
    count = 0;
    curnode = plist->tail;
    while (curnode != 0) {
        if (((void *)curnode < bptr) || ((void *)curnode > eptr)) {
            return FALSE;
        }
        
        if (++count > plist->inum) {
            return FALSE;
        }
        curnode = curnode->priv;
    }
    
    if (count != plist->inum) {
        return FALSE;
    }
    
    return TRUE;
}

